#include "databasehandler.h"
#include <QSqlError>
#include <QDebug>

// 构造函数，初始化数据库连接
DatabaseHandler::DatabaseHandler(QObject *parent) : QObject(parent)
{
    // 确保在初始化时关闭任何已打开的数据库连接
    if (db.isOpen())
        db.close();
}

/*
 * 连接到数据库
 * 参数: dbName - 数据库的文件路径
 * 返回: 连接成功返回 true，失败返回 false
 */
bool DatabaseHandler::connectToDatabase(const QString &dbName)
{
    // 检查是否已经存在默认的数据库连接
    if (QSqlDatabase::contains("qt_sql_default_connection")) {
        db = QSqlDatabase::database("qt_sql_default_connection"); // 获取现有连接
    } else {
        db = QSqlDatabase::addDatabase("QSQLITE"); // 添加新的 SQLite 数据库连接
    }

    db.setDatabaseName(dbName); // 设置数据库文件名

    // 尝试打开数据库
    if (!db.open()) {
        // 打开失败，输出错误信息
        qWarning() << "Failed to open database:" << db.lastError().text();
        return false; // 连接失败
    }

    qDebug() << "Database connected successfully"; // 输出连接成功信息
    return true; // 连接成功
}

bool DatabaseHandler::executeQuery(QSqlQuery &query, const QString &queryStr)
{
    if (!query.exec(queryStr)) {
        qWarning() << "Query execution failed:" << query.lastError().text(); // 执行失败，输出错误信息
        return false;
    }
    return true;
}

/*
 * 查询数据，封装成 JSON
 * 参数: queryStr - SQL 查询字符串
 */
void DatabaseHandler::fetchData(const QString &queryStr)
{
    QSqlQuery query;
    if (!executeQuery(query, queryStr)) { // 使用执行查询的函数
        qDebug() << "Query execution failed:" << query.lastError(); // 输出错误信息
        return; // 退出函数
    }

    dataContainer.clear(); // 清空容器
    QJsonArray dataArrayJson; // JSON 数组

    // 遍历查询结果，将每行数据存入 dataContainer 和 dataArrayJson
    while (query.next()) {
        QVariantList row; // 存储行数据
        for (int i = 0; i < query.record().count(); ++i) {
            QVariant value = query.value(i); // 获取列值
            row << value; // 将每列数据插入到行列表中
            dataArrayJson.append(QJsonValue::fromVariant(value)); // 添加到 JSON 数组
        }
        dataContainer << row; // 将整行添加到数据容器
    }

    result["data"] = dataArrayJson; // 封装成 JSON 对象
    qDebug() << "Fetched rows:" << dataContainer.size(); // 输出获取到的行数
}

/*
 * 打印出从数据库查出的数据
 */
void DatabaseHandler::printData() const
{
    // 遍历容器中的数据，打印每一行每一列
    for (const auto &row : dataContainer) {
        for (const auto &col : row) {
            qDebug() << col.toString(); // 打印列值
        }
        qDebug() << "-----"; // 分隔每行
    }
}
